/*
 *    Webical - http://www.webical.org
 *    Copyright (C) 2007 Func. Internet Integration
 *
 *    This file is part of Webical.
 *
 *    This program is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.webical.web.component.calendar;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.wicket.extensions.markup.html.form.DateTextField;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.StringResourceModel;
import org.webical.web.action.DaySelectedAction;
import org.webical.web.action.IAction;
import org.webical.web.component.AbstractBasePanel;
import org.webical.web.component.behavior.FormComponentValidationStyleBehavior;
import org.webical.web.component.calendar.model.DatePickerModel;

/**
 * Panel to pick a specific date and show it
 *
 * @author Mattijs Hoitink
 *
 */
public abstract class DatePickerPanel extends AbstractBasePanel {
	private static final long serialVersionUID = 1L;

	@SuppressWarnings("unchecked")
	protected static Class[] PANELACTIONS = new Class[] { };

	private static Log log = LogFactory.getLog(DatePickerPanel.class);

	/* Markup ID's */
	private static final String DATE_PICKER_FORM_MARKUP_ID = "datePickerForm";
	private static final String DATE_PICKER_ROW_REPEATER_MARKUP_ID = "datePickerRowRepeater";

	private DatePickerModel datePickerModel;
	private GregorianCalendar currentDate;

	private Label monthLabel;

	/**
	 * Constructor
	 * @param markupId The ID used in the markup
	 * @param model The model to use for the date
	 */
	public DatePickerPanel(String markupId, CompoundPropertyModel datePickerCompoundPropertyModel) {
		super(markupId, DatePickerPanel.class);

		this.datePickerModel = (DatePickerModel) datePickerCompoundPropertyModel.getObject();
		this.currentDate = (GregorianCalendar) datePickerModel.getCurrentDate();

		setModel(datePickerCompoundPropertyModel);
	}

	/* (non-Javadoc)
	 * @see org.webical.web.components.IAccessibilitySwitchingComponent#setupCommonComponents()
	 */
	public void setupCommonComponents() {
		//NOT NEEDED
	}

	/* (non-Javadoc)
	 * @see org.webical.web.components.IAccessibilitySwitchingComponent#setupAccessibleComponents()
	 */
	public void setupAccessibleComponents() {
		// Add a feedback panel
		FeedbackPanel datePickerFeedBackPanel = new FeedbackPanel("datePickerFeedbackPanel");
		add(datePickerFeedBackPanel);

		// Add the date form
		DatePickerForm form = new DatePickerForm(DATE_PICKER_FORM_MARKUP_ID, getModel());
		form.add(new FormComponentValidationStyleBehavior());

        addOrReplace(form);

        DatePickerRowRepeater rowRepeater = new DatePickerRowRepeater(DATE_PICKER_ROW_REPEATER_MARKUP_ID, currentDate) {
			private static final long serialVersionUID = 1L;

			@Override
			public void onAction(IAction action) {
				DatePickerPanel.this.onAction(action);
			}

        };
        addOrReplace(rowRepeater);

        renderModelDependantLabels();
	}

	/* (non-Javadoc)
	 * @see org.webical.web.components.IAccessibilitySwitchingComponent#setupNonAccessibleComponents()
	 */
	public void setupNonAccessibleComponents() {
		// NOTHING TO DO (YET?)
	}

	@Override
	protected void onModelChanged() {
		renderModelDependantLabels();
	}

	private void renderModelDependantLabels() {
		SimpleDateFormat dateFormatter = new SimpleDateFormat("MMMM yyyy", getLocale());
		// Add a month label
		monthLabel = new Label("monthLabel", dateFormatter.format(currentDate.getTime()));
		addOrReplace(monthLabel);
	}

	/**
	 * Handle actions generated by this panel.
	 *
	 * @param action The action to handle
	 */
	public abstract void onAction(IAction action);


	/* Date Form */

	/**
	 * Form with the Date selection field
	 * @author Mattijs Hoitink
	 *
	 */
	private class DatePickerForm extends Form {
		private static final long serialVersionUID = 1L;

		private static final String CHANGE_DATE_LABEL = "change_date_label";
		private static final String CHANGE_DATE_BUTTON_MARKUP_ID = "changeDateButton";
		private static final String CURRENT_DATE_FIELD_MARKUP_ID = "changeDateField";
		private static final String CHANGE_DATE_LABEL_MARKUP_ID = "changeDateLabel";

		private Label changeDateLabel;
		private DateTextField changeDateTextField;
		private Button changeDateButton;
		private StringResourceModel changeDateResourceModel;

		/**
		 * Constructor
		 * @param markupId the id used in the markup
		 * @param model a CompoundPropertyModel containing an Input object with the selected date
		 */
		public DatePickerForm(String markupId, IModel model) {
			super(markupId, model);

			changeDateResourceModel = new StringResourceModel(CHANGE_DATE_LABEL, this, null);

			changeDateTextField = new DateTextField(CURRENT_DATE_FIELD_MARKUP_ID);
			changeDateLabel = new Label(CHANGE_DATE_LABEL_MARKUP_ID, changeDateResourceModel);
			changeDateButton = new Button(CHANGE_DATE_BUTTON_MARKUP_ID, changeDateResourceModel);

			add(changeDateLabel);
			add(changeDateTextField);
			add(changeDateButton);
		}

		/* (non-Javadoc)
		 * @see org.apache.wicket.markup.html.form.Form#onSubmit()
		 */
		@Override
		protected void onSubmit() {
			GregorianCalendar dayCal = new GregorianCalendar();
			dayCal.setTime((Date) changeDateTextField.getConvertedInput());
			DatePickerPanel.this.onAction(new DaySelectedAction(dayCal));
		}

	}

}
